home *** CD-ROM | disk | FTP | other *** search
/ Aminet 6 / Aminet 6 - June 1995.iso / Aminet / gfx / 3d / irit50src.lha / irit5 / irit / freefrm3.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-01-02  |  55.0 KB  |  1,345 lines

  1. /*****************************************************************************
  2. *   "Irit" - the 3d (not only polygonal) solid modeller.             *
  3. *                                         *
  4. * Written by:  Gershon Elber                Ver 0.2, Mar. 1990   *
  5. ******************************************************************************
  6. *   Module to provide the required interfact for the cagd library for the    *
  7. * free form surfaces and curves.                         *
  8. *****************************************************************************/
  9.  
  10. #include <stdio.h>
  11. #include <math.h>
  12. #include "program.h"
  13. #include "allocate.h"
  14. #include "attribut.h"
  15. #include "objects.h"
  16. #include "primitiv.h"
  17. #include "windows.h"
  18. #include "ip_cnvrt.h"
  19. #include "freeform.h"
  20.  
  21. /*****************************************************************************
  22. * DESCRIPTION:                                                               M
  23. * Editing of a single control point of a curve.                          M
  24. *                                                                            *
  25. * PARAMETERS:                                                                M
  26. *   PObjCrv:   Curve to edit one of its control points.                      M
  27. *   Pt:        Ptoint to replace PObjCrv's Index point.                      M
  28. *   Index:     Index of point to replace in PObjCrv's control polygon.       M
  29. *                                                                            *
  30. * RETURN VALUE:                                                              M
  31. *   IPObjectStruct *:   A new curve after the replacement.                   M
  32. *                                                                            *
  33. * KEYWORDS:                                                                  M
  34. *   EditCrvControlPoint                                                      M
  35. *****************************************************************************/
  36. IPObjectStruct *EditCrvControlPoint(IPObjectStruct *PObjCrv,
  37.                     CagdCtlPtStruct *Pt,
  38.                     RealType *Index)
  39. {
  40.     IPObjectStruct *CrvObj;
  41.     CagdCrvStruct *Crv;
  42.  
  43.     Crv = CagdEditSingleCrvPt(PObjCrv -> U.Crvs, Pt,
  44.                   REAL_PTR_TO_INT(Index), TRUE);
  45.  
  46.     CrvObj = GenCRVObject(Crv);
  47.  
  48.     return CrvObj;
  49. }
  50.  
  51. /*****************************************************************************
  52. * DESCRIPTION:                                                               M
  53. * Editing of a single control point of a surface.                 M
  54. *                                                                            *
  55. * PARAMETERS:                                                                M
  56. *   PObjSrf:        Surface to edit one of its control points.               M
  57. *   Pt:             Ptoint to replace PObjSrf's U/VIndex point.              M
  58. *   UIndex, VIndex: Indices of point to replace in PObjCrv's control mesh.   M
  59. *                                                                            *
  60. * RETURN VALUE:                                                              M
  61. *   IPObjectStruct *:   A new surface after the replacement.                 M
  62. *                                                                            *
  63. * KEYWORDS:                                                                  M
  64. *   EditSrfControlPoint                                                      M
  65. *****************************************************************************/
  66. IPObjectStruct *EditSrfControlPoint(IPObjectStruct *PObjSrf,
  67.                     CagdCtlPtStruct *Pt,
  68.                     RealType *UIndex,
  69.                     RealType *VIndex)
  70. {
  71.     IPObjectStruct *SrfObj;
  72.     CagdSrfStruct *Srf;
  73.  
  74.     Srf = CagdEditSingleSrfPt(PObjSrf -> U.Srfs, Pt,
  75.                   REAL_PTR_TO_INT(UIndex),
  76.                   REAL_PTR_TO_INT(VIndex), TRUE);
  77.  
  78.     SrfObj = GenSRFObject(Srf);
  79.  
  80.     return SrfObj;
  81. }
  82.  
  83. /*****************************************************************************
  84. * DESCRIPTION:                                                               M
  85. * Raises the degree of the given curve.                                      M
  86. *                                                                            *
  87. * PARAMETERS:                                                                M
  88. *   PObjCrv:     Curve to raise its degree.                                  M
  89. *   RNewOrder:   New degree of curve.                                        M
  90. *                                                                            *
  91. * RETURN VALUE:                                                              M
  92. *   IPObjectStruct *:  Curve identical to PObjCrv, but with RNewOrder Order. M
  93. *                                                                            *
  94. * KEYWORDS:                                                                  M
  95. *   RaiseCurveObject                                                         M
  96. *****************************************************************************/
  97. IPObjectStruct *RaiseCurveObject(IPObjectStruct *PObjCrv, RealType *RNewOrder)
  98. {
  99.     IPObjectStruct *CrvObj;
  100.     CagdCrvStruct
  101.     *Crv = PObjCrv -> U.Crvs;
  102.     int OldOrder = Crv -> Order,
  103.     NewOrder = REAL_PTR_TO_INT(RNewOrder);
  104.  
  105.     if (NewOrder <= OldOrder) {
  106.     IritPrsrFatalError("Order to raise less the current");
  107.     return NULL;
  108.     }
  109.  
  110.     Crv = CagdCrvDegreeRaiseN(Crv, NewOrder);
  111.  
  112.     CrvObj = GenCRVObject(Crv);
  113.  
  114.     return CrvObj;
  115. }
  116.  
  117. /*****************************************************************************
  118. * DESCRIPTION:                                                               M
  119. * Raises the degree of the given surface.                                    M
  120. *                                                                            M
  121. *                                                                            *
  122. * PARAMETERS:                                                                M
  123. *   PObjSrf:     Surface to raise its degree.                                M
  124. *   RDir:        Direction to raise degre. Either U or V.                    M
  125. *   RNewOrder:   New degree of surface.                                      M
  126. *                                                                            *
  127. * RETURN VALUE:                                                              M
  128. *   IPObjectStruct *:  Surface identical tor PObjSrf, but with RNewOrder     M
  129. *               Order in direction RDir.                     M
  130. *                                                                            *
  131. * KEYWORDS:                                                                  M
  132. *   RaiseSurfaceObject                                                       M
  133. *                                                                            M
  134. *****************************************************************************/
  135. IPObjectStruct *RaiseSurfaceObject(IPObjectStruct *PObjSrf,
  136.                    RealType *RDir,
  137.                    RealType *RNewOrder)
  138. {
  139.     IPObjectStruct *SrfObj;
  140.     CagdSrfStruct *TSrf,
  141.     *Srf = PObjSrf -> U.Srfs;
  142.     int Dir = REAL_PTR_TO_INT(RDir),
  143.     OldOrder = Dir == CAGD_CONST_U_DIR ? Srf -> VOrder : Srf -> UOrder,
  144.     NewOrder = REAL_PTR_TO_INT(RNewOrder);
  145.  
  146.     if (NewOrder <= OldOrder) {
  147.     WndwInputWindowPutStr("Order to raise less the current");
  148.     return NULL;
  149.     }
  150.  
  151.     while (OldOrder++ < NewOrder) {
  152.     TSrf = CagdSrfDegreeRaise(Srf, Dir);
  153.     if (Srf != PObjSrf -> U.Srfs)
  154.         CagdSrfFree(Srf);
  155.     Srf = TSrf;
  156.     }
  157.  
  158.     SrfObj = GenSRFObject(Srf);
  159.  
  160.     return SrfObj;
  161. }
  162.  
  163. /*****************************************************************************
  164. * DESCRIPTION:                                                               M
  165. * Make, in place, the following two curves or surfaces compatible.           M
  166. *                                                                            *
  167. * PARAMETERS:                                                                M
  168. *   PObj1, PObj2:  Two curve or two surfaces to make compatible in order,    M
  169. *           point type and continuity.                                M
  170. *                                                                            *
  171. * RETURN VALUE:                                                              M
  172. *   void                                                                     M
  173. *                                                                            *
  174. * KEYWORDS:                                                                  M
  175. *   MakeFreeFormCompatible                                                   M
  176. *****************************************************************************/
  177. void MakeFreeFormCompatible(IPObjectStruct *PObj1, IPObjectStruct *PObj2)
  178. {
  179.     if (IP_IS_CRV_OBJ(PObj1) && IP_IS_CRV_OBJ(PObj2)) {
  180.         if (!CagdMakeCrvsCompatible(&PObj1 -> U.Crvs,
  181.                     &PObj2 -> U.Crvs, TRUE, TRUE))
  182.         WndwInputWindowPutStr("Failed in making curves compatible.");
  183.     }
  184.     else if (IP_IS_SRF_OBJ(PObj1) && IP_IS_SRF_OBJ(PObj2)) {
  185.     if (!CagdMakeSrfsCompatible(&PObj1 -> U.Srfs,
  186.                     &PObj2 -> U.Srfs,
  187.                     TRUE, TRUE, TRUE, TRUE))
  188.         WndwInputWindowPutStr("Failed in making surfaces compatible.");
  189.     }
  190.     else {
  191.     WndwInputWindowPutStr("Only two surfaces or two curves expected.");
  192.     }
  193. }
  194.  
  195. /*****************************************************************************
  196. * DESCRIPTION:                                                               M
  197. * Computes a new curve, which is the blend of the given two compatible       M
  198. * curves.                                                                    M
  199. *                                                                            *
  200. * PARAMETERS:                                                                M
  201. *   PObjCrv1, PObjCrv2:  Two curves to blend.                                M
  202. *   Method:              Method of blending:                                 M
  203. *             0 - simple linear interpolation between PObjCrv?.   M
  204. *             1/3 - corner cutting morphing technique.         M
  205. *                   scale to same length all time.             M
  206. *                   If 3, also filters out tangency test.         M
  207. *                        2/4 - same as 1 but scale to same bbox all time.    M
  208. *                   If 4, also filters out tangency test.         M
  209. *                        5 - multires morphing.                     M
  210. *   Blend:               Parameter of blend. Usually between zero and one    M
  211. *             form methods 0 and 3, distance between adjacent     M
  212. *             morphed curves from method 1 and 2.             M
  213. *                                                                            *
  214. * RETURN VALUE:                                                              M
  215. *   IPObjectStruct *:    Single blended curve if Method = 0, List of curves  M
  216. *             forming the entire corner cutting morphing if       M
  217. *             Method = 1.                         M
  218. *                                                                            *
  219. * KEYWORDS:                                                                  M
  220. *   TwoCrvsMorphing                                                          M
  221. *****************************************************************************/
  222. IPObjectStruct *TwoCrvsMorphing(IPObjectStruct *PObjCrv1,
  223.                 IPObjectStruct *PObjCrv2,
  224.                 RealType *Method,
  225.                 RealType *Blend)
  226. {
  227.     IPObjectStruct *CrvObj;
  228.     CagdCrvStruct
  229.         *Crv = NULL;
  230.  
  231.     switch (REAL_PTR_TO_INT(Method)) {
  232.     case 0:
  233.         Crv = SymbTwoCrvsMorphing(PObjCrv1 -> U.Crvs, PObjCrv2 -> U.Crvs,
  234.                                        *Blend);
  235.         break;
  236.     case 1:
  237.         Crv = SymbTwoCrvsMorphingCornerCut(PObjCrv1 -> U.Crvs,
  238.                            PObjCrv2 -> U.Crvs,
  239.                            *Blend, FALSE, FALSE);
  240.         break;
  241.     case 2:
  242.         Crv = SymbTwoCrvsMorphingCornerCut(PObjCrv1 -> U.Crvs,
  243.                            PObjCrv2 -> U.Crvs,
  244.                            *Blend, TRUE, FALSE);
  245.         break;
  246.     case 3:
  247.         Crv = SymbTwoCrvsMorphingCornerCut(PObjCrv1 -> U.Crvs,
  248.                            PObjCrv2 -> U.Crvs,
  249.                            *Blend, FALSE, TRUE);
  250.         break;
  251.     case 4:
  252.         Crv = SymbTwoCrvsMorphingCornerCut(PObjCrv1 -> U.Crvs,
  253.                            PObjCrv2 -> U.Crvs,
  254.                            *Blend, TRUE, TRUE);
  255.         break;
  256.     case 5:
  257.         if (CAGD_IS_BEZIER_CRV(PObjCrv1 -> U.Crvs)) {
  258.         CagdCrvStruct
  259.             *Crv1 = CnvrtBezier2BsplineCrv(PObjCrv1 -> U.Crvs),
  260.             *Crv2 = CnvrtBezier2BsplineCrv(PObjCrv2 -> U.Crvs);
  261.  
  262.         Crv = SymbTwoCrvsMorphingMultiRes(Crv1, Crv2, *Blend);
  263.         CagdCrvFree(Crv1);
  264.         CagdCrvFree(Crv2);
  265.         }
  266.         else
  267.         Crv = SymbTwoCrvsMorphingMultiRes(PObjCrv1 -> U.Crvs,
  268.                           PObjCrv2 -> U.Crvs,
  269.                           *Blend);
  270.         break;
  271.     default:
  272.         WndwInputWindowPutStr("Wrong curve morphing method.\n");
  273.         return NULL;
  274.     }
  275.  
  276.     if (Crv == NULL) {
  277.     WndwInputWindowPutStr("Curve are incompatible, use FFCOMPAT first.");
  278.     return NULL;
  279.     }
  280.  
  281.     if (Crv -> Pnext != NULL) {
  282.     int i;
  283.     IPObjectStruct *PObj;
  284.  
  285.     CrvObj = IPAllocObject("", IP_OBJ_LIST_OBJ, NULL);
  286.     for (i = 0; Crv != NULL; Crv = Crv -> Pnext, i++)
  287.         ListObjectInsert(CrvObj, i, GenCRVObject(Crv));
  288.     ListObjectInsert(CrvObj, i, NULL);
  289.     for (i = 0; (PObj = ListObjectGet(CrvObj, i)) != NULL; i++)
  290.         PObj -> U.Crvs -> Pnext = NULL;
  291.     }
  292.     else
  293.     CrvObj = GenCRVObject(Crv);
  294.  
  295.     return CrvObj;
  296. }
  297.  
  298. /*****************************************************************************
  299. * DESCRIPTION:                                                               M
  300. * Computes a new surface, which is the blend of the given two compatible     M
  301. * surfaces.                                     M
  302. *                                                                            *
  303. * PARAMETERS:                                                                M
  304. *   PObjCrv1, PObjCrv2:  Two surfaces to blend.                              M
  305. *   Blend:               Parameter of blend. Usually between zero and one.   M
  306. *                                                                            *
  307. * RETURN VALUE:                                                              M
  308. *   IPObjectStruct *:    Blended surface.                                    M
  309. *                                                                            *
  310. * KEYWORDS:                                                                  M
  311. *   TwoSrfsMorphing                                                          M
  312. *****************************************************************************/
  313. IPObjectStruct *TwoSrfsMorphing(IPObjectStruct *PObjSrf1,
  314.                 IPObjectStruct *PObjSrf2,
  315.                 RealType *Blend)
  316. {
  317.     IPObjectStruct *SrfObj;
  318.     CagdSrfStruct
  319.     *Srf = SymbTwoSrfsMorphing(PObjSrf1 -> U.Srfs, PObjSrf2 -> U.Srfs,
  320.                                        *Blend);
  321.  
  322.     if (Srf == NULL) {
  323.     WndwInputWindowPutStr("Surfaces are incompatible, use FFCOMPAT first.");
  324.     return NULL;
  325.     }
  326.     SrfObj = GenSRFObject(Srf);
  327.  
  328.     return SrfObj;
  329. }
  330.  
  331. /*****************************************************************************
  332. * DESCRIPTION:                                                               M
  333. * Converts a Bezier curve or surface into a Bspline curve or surface.        M
  334. *                                                                            *
  335. * PARAMETERS:                                                                M
  336. *   PObj:      Bezier geometry to convert to Bspline geometry.               M
  337. *                                                                            *
  338. * RETURN VALUE:                                                              M
  339. *   IPObjectStruct *:   Same geometry as PObj but as Bspline.                M
  340. *                                                                            *
  341. * KEYWORDS:                                                                  M
  342. *   CnvrtBezierToBspline                                                     M
  343. *****************************************************************************/
  344. IPObjectStruct *CnvrtBezierToBspline(IPObjectStruct *PObj)
  345. {
  346.     if (PObj -> ObjType == IP_OBJ_SURFACE) {
  347.     CagdSrfStruct *Srf = CnvrtBezier2BsplineSrf(PObj -> U.Srfs);
  348.  
  349.     return GenSRFObject(Srf);
  350.     }
  351.     else if (PObj -> ObjType == IP_OBJ_CURVE) {
  352.     CagdCrvStruct *Crv = CnvrtBezier2BsplineCrv(PObj -> U.Crvs);
  353.  
  354.     return GenCRVObject(Crv);
  355.     }
  356.     else {
  357.         IritFatalError("Only surface/curve expected.");
  358.         return NULL;
  359.     }
  360. }
  361.  
  362. /*****************************************************************************
  363. * DESCRIPTION:                                                               M
  364. * Convert a Bspline curve or surface into list of Bezier curves or surfaces. M
  365. *                                                                            *
  366. * PARAMETERS:                                                                M
  367. *   PObj:     A Bspline geometry to convert to a Bezier geometry.            M
  368. *                                                                            *
  369. * RETURN VALUE:                                                              M
  370. *   IPObjectStruct *:  A Bezier geometry representing same geometry as PObj. M
  371. *                                                                            *
  372. * KEYWORDS:                                                                  M
  373. *   CnvrtBsplineToBezier                                                     M
  374. *****************************************************************************/
  375. IPObjectStruct *CnvrtBsplineToBezier(IPObjectStruct *PObj)
  376. {
  377.     if (PObj -> ObjType == IP_OBJ_SURFACE) {
  378.     CagdSrfStruct *TSrf,
  379.         *Srf = CnvrtBspline2BezierSrf(PObj -> U.Srfs);
  380.  
  381.     if (Srf -> Pnext == NULL)
  382.         return GenSRFObject(Srf);
  383.     else {
  384.         int i;
  385.         IPObjectStruct
  386.         *PObjList = IPAllocObject("", IP_OBJ_LIST_OBJ, NULL);
  387.  
  388.         for (i = 0; Srf != NULL; i++) {
  389.             ListObjectInsert(PObjList, i, GenSRFObject(Srf));
  390.         AttrSetObjectColor(ListObjectGet(PObjList, i),
  391.                    AttrGetObjectColor(PObj));
  392.  
  393.         TSrf = Srf -> Pnext;
  394.         Srf -> Pnext = NULL;
  395.         Srf = TSrf;
  396.         }
  397.         ListObjectInsert(PObjList, i, NULL);
  398.  
  399.         return PObjList;
  400.     }                   
  401.     }
  402.     else if (PObj -> ObjType == IP_OBJ_CURVE) {
  403.     CagdCrvStruct *TCrv,
  404.         *Crv = CnvrtBspline2BezierCrv(PObj -> U.Crvs);
  405.  
  406.     if (Crv -> Pnext == NULL)
  407.         return GenCRVObject(Crv);
  408.     else {
  409.         int i;
  410.         IPObjectStruct
  411.         *PObjList = IPAllocObject("", IP_OBJ_LIST_OBJ, NULL);
  412.  
  413.         for (i = 0; Crv != NULL; i++) {
  414.             ListObjectInsert(PObjList, i, GenCRVObject(Crv));
  415.         AttrSetObjectColor(ListObjectGet(PObjList, i),
  416.                    AttrGetObjectColor(PObj));
  417.  
  418.         TCrv = Crv -> Pnext;
  419.         Crv -> Pnext = NULL;
  420.         Crv = TCrv;
  421.         }
  422.         ListObjectInsert(PObjList, i, NULL);
  423.  
  424.         return PObjList;
  425.     }                   
  426.     }
  427.     else {
  428.         IritFatalError("Only surface/curve expected.");
  429.         return NULL;
  430.     }
  431. }
  432.  
  433. /*****************************************************************************
  434. * DESCRIPTION:                                                               M
  435. * Computes a new curve/surface that is the result of the product of the      M
  436. * given two curves or surfaces.                                              M
  437. *                                                                            *
  438. * PARAMETERS:                                                                M
  439. *   PObj1, PObj2: Two curves or surfaces to multiply.                        M
  440. *                                                                            *
  441. * RETURN VALUE:                                                              M
  442. *   IPObjectStruct *:    Product result.                                     M
  443. *                                                                            *
  444. * KEYWORDS:                                                                  M
  445. *   TwoCrvsSrfsProduct                                                       M
  446. *****************************************************************************/
  447. IPObjectStruct *TwoCrvsSrfsProduct(IPObjectStruct *PObj1,
  448.                    IPObjectStruct *PObj2)
  449. {
  450.     IPObjectStruct
  451.     *Obj = NULL;
  452.  
  453.     if (IP_IS_SRF_OBJ(PObj1) && IP_IS_SRF_OBJ(PObj2)) {
  454.     CagdSrfStruct
  455.         *Srf = SymbSrfMult(PObj1 -> U.Srfs, PObj2 -> U.Srfs);
  456.  
  457.     Obj = Srf ? GenSRFObject(Srf) : NULL;
  458.     }
  459.     else if (IP_IS_CRV_OBJ(PObj1) && IP_IS_CRV_OBJ(PObj2)) {
  460.     CagdCrvStruct
  461.         *Crv = SymbCrvMult(PObj1 -> U.Crvs, PObj2 -> U.Crvs);
  462.  
  463.     Obj = Crv ? GenCRVObject(Crv) : NULL;
  464.     }
  465.     else {
  466.     IritFatalError("Pair of curves or pair of surfaces expected.");
  467.     }
  468.  
  469.     return Obj;
  470. }
  471.  
  472. /*****************************************************************************
  473. * DESCRIPTION:                                                               M
  474. * Computes a new scalar curve/surface that is the result of the dot product  M
  475. * of the given two curves or surfaces.                                       M
  476. *                                                                            *
  477. * PARAMETERS:                                                                M
  478. *   PObj1, PObj2: Two curves or surfaces to multiply.                        M
  479. *                                                                            *
  480. * RETURN VALUE:                                                              M
  481. *   IPObjectStruct *:    Product result.                                     M
  482. *                                                                            *
  483. * KEYWORDS:                                                                  M
  484. *   TwoCrvsSrfsDotProduct                                                    M
  485. *****************************************************************************/
  486. IPObjectStruct *TwoCrvsSrfsDotProduct(IPObjectStruct *PObj1,
  487.                       IPObjectStruct *PObj2)
  488. {
  489.     IPObjectStruct
  490.     *Obj = NULL;
  491.  
  492.     if (IP_IS_SRF_OBJ(PObj1) && IP_IS_SRF_OBJ(PObj2)) {
  493.     CagdSrfStruct
  494.         *Srf = SymbSrfDotProd(PObj1 -> U.Srfs, PObj2 -> U.Srfs);
  495.  
  496.     Obj = Srf ? GenSRFObject(Srf) : NULL;
  497.     }
  498.     else if (IP_IS_CRV_OBJ(PObj1) && IP_IS_CRV_OBJ(PObj2)) {
  499.     CagdCrvStruct
  500.         *Crv = SymbCrvDotProd(PObj1 -> U.Crvs, PObj2 -> U.Crvs);
  501.  
  502.     Obj = Crv ? GenCRVObject(Crv) : NULL;
  503.     }
  504.     else {
  505.     IritFatalError("Pair of curves or pair of surfaces expected.");
  506.     }
  507.  
  508.     return Obj;
  509. }
  510.  
  511. /*****************************************************************************
  512. * DESCRIPTION:                                                               M
  513. * Computes a new curve/surface that is the result of the cross product       M
  514. * of the given two curves or surfaces.                                    M
  515. *                                                                            *
  516. * PARAMETERS:                                                                M
  517. *   PObj1, PObj2: Two curves or surfaces to multiply.                        M
  518. *                                                                            *
  519. * RETURN VALUE:                                                              M
  520. *   IPObjectStruct *:    Product result.                                     M
  521. *                                                                            *
  522. * KEYWORDS:                                                                  M
  523. *   TwoCrvsSrfsCrossProduct                                                  M
  524. *****************************************************************************/
  525. IPObjectStruct *TwoCrvsSrfsCrossProduct(IPObjectStruct *PObj1,
  526.                     IPObjectStruct *PObj2)
  527. {
  528.     IPObjectStruct
  529.     *Obj = NULL;
  530.  
  531.     if (IP_IS_SRF_OBJ(PObj1) && IP_IS_SRF_OBJ(PObj2)) {
  532.     CagdSrfStruct
  533.         *Srf = SymbSrfCrossProd(PObj1 -> U.Srfs, PObj2 -> U.Srfs);
  534.  
  535.     Obj = Srf ? GenSRFObject(Srf) : NULL;
  536.     }
  537.     else if (IP_IS_CRV_OBJ(PObj1) && IP_IS_CRV_OBJ(PObj2)) {
  538.     CagdCrvStruct
  539.         *Crv = SymbCrvCrossProd(PObj1 -> U.Crvs, PObj2 -> U.Crvs);
  540.  
  541.     Obj = Crv ? GenCRVObject(Crv) : NULL;
  542.     }
  543.     else {
  544.     IritFatalError("Pair of curves or pair of surfaces expected.");
  545.     }
  546.  
  547.     return Obj;
  548. }
  549.  
  550. /*****************************************************************************
  551. * DESCRIPTION:                                                               M
  552. * Computes a new curve/surface that is the result of the sum of the given    M
  553. * two curves or surfaces.                                               M
  554. *                                                                            *
  555. * PARAMETERS:                                                                M
  556. *   PObj1, PObj2: Two curves or surfaces to add up.                          M
  557. *                                                                            *
  558. * RETURN VALUE:                                                              M
  559. *   IPObjectStruct *:    Summation result.                                   M
  560. *                                                                            *
  561. * KEYWORDS:                                                                  M
  562. *   TwoCrvsSrfsSum                                                           M
  563. *****************************************************************************/
  564. IPObjectStruct *TwoCrvsSrfsSum(IPObjectStruct *PObj1, IPObjectStruct *PObj2)
  565. {
  566.     IPObjectStruct
  567.     *Obj = NULL;
  568.  
  569.     if (IP_IS_SRF_OBJ(PObj1) && IP_IS_SRF_OBJ(PObj2)) {
  570.     CagdSrfStruct
  571.         *Srf = SymbSrfAdd(PObj1 -> U.Srfs, PObj2 -> U.Srfs);
  572.  
  573.     Obj = Srf ? GenSRFObject(Srf) : NULL;
  574.     }
  575.     else if (IP_IS_CRV_OBJ(PObj1) && IP_IS_CRV_OBJ(PObj2)) {
  576.     CagdCrvStruct
  577.         *Crv = SymbCrvAdd(PObj1 -> U.Crvs, PObj2 -> U.Crvs);
  578.  
  579.     Obj = Crv ? GenCRVObject(Crv) : NULL;
  580.     }
  581.     else {
  582.     IritFatalError("Pair of curves or pair of surfaces expected.");
  583.     }
  584.  
  585.     return Obj;
  586. }
  587.  
  588. /*****************************************************************************
  589. * DESCRIPTION:                                                               M
  590. * Computes a new curve/surface that is the result of the difference of the   M
  591. * given two curves or surfaces.                                       M
  592. *                                                                            *
  593. * PARAMETERS:                                                                M
  594. *   PObj1, PObj2: Two curves or surfaces to subtract.                        M
  595. *                                                                            *
  596. * RETURN VALUE:                                                              M
  597. *   IPObjectStruct *:    Subtraction result.                                 M
  598. *                                                                            *
  599. * KEYWORDS:                                                                  M
  600. *   TwoCrvsSrfsDiff                                                          M
  601. *****************************************************************************/
  602. IPObjectStruct *TwoCrvsSrfsDiff(IPObjectStruct *PObj1, IPObjectStruct *PObj2)
  603. {
  604.     IPObjectStruct
  605.     *Obj = NULL;
  606.  
  607.     if (IP_IS_SRF_OBJ(PObj1) && IP_IS_SRF_OBJ(PObj2)) {
  608.     CagdSrfStruct
  609.         *Srf = SymbSrfSub(PObj1 -> U.Srfs, PObj2 -> U.Srfs);
  610.  
  611.     Obj = Srf ? GenSRFObject(Srf) : NULL;
  612.     }
  613.     else if (IP_IS_CRV_OBJ(PObj1) && IP_IS_CRV_OBJ(PObj2)) {
  614.     CagdCrvStruct
  615.         *Crv = SymbCrvSub(PObj1 -> U.Crvs, PObj2 -> U.Crvs);
  616.  
  617.     Obj = Crv ? GenCRVObject(Crv) : NULL;
  618.     }
  619.     else {
  620.     IritFatalError("Pair of curves or pair of surfaces expected.");
  621.     }
  622.  
  623.     return Obj;
  624. }
  625.  
  626. /*****************************************************************************
  627. * DESCRIPTION:                                                               M
  628. * Compute the inflection points of a curve.                     M
  629. *                                                                            *
  630. * PARAMETERS:                                                                M
  631. *   PObj:      Curve to compute inflection points for.                       M
  632. *   Eps:       Accuracy of computation.                                      M
  633. *                                                                            *
  634. * RETURN VALUE:                                                              M
  635. *   IPObjectStruct *:  Either inflection locations if Eps > 0, or         M
  636. *                      curvature field sign curve if Eps < 0.                M
  637. *                                                                            *
  638. * KEYWORDS:                                                                  M
  639. *   CrvInflectionPts                                                         M
  640. *****************************************************************************/
  641. IPObjectStruct *CrvInflectionPts(IPObjectStruct *PObj, RealType *Eps)
  642. {
  643.     IPObjectStruct *NewPObj;
  644.  
  645.     if (*Eps <= 0.0) {
  646.     CagdRType TMin, TMax;
  647.     CagdCrvStruct *InflectCrv2D,
  648.         *InflectCrv = SymbCrv2DCurvatureSign(PObj -> U.Crvs);
  649.  
  650.     CagdCrvDomain(PObj -> U.Crvs, &TMin, &TMax);
  651.     InflectCrv2D = SymbPrmtSclrCrvTo2D(InflectCrv, TMin, TMax);
  652.     CagdCrvFree(InflectCrv);
  653.  
  654.     NewPObj = GenCRVObject(InflectCrv2D);
  655.     }
  656.     else {
  657.     int i;
  658.     CagdPtStruct *IPtsTmp,
  659.         *IPts = SymbCrv2DInflectionPts(PObj -> U.Crvs, *Eps);
  660.  
  661.     NewPObj = IPAllocObject("", IP_OBJ_LIST_OBJ, NULL);
  662.  
  663.     for (IPtsTmp = IPts, i = 0;
  664.          IPtsTmp != NULL;
  665.          IPtsTmp = IPtsTmp -> Pnext, i++) {
  666.         ListObjectInsert(NewPObj, i, GenNUMValObject(IPtsTmp -> Pt[0]));
  667.     }
  668.  
  669.     CagdPtFreeList(IPts);
  670.  
  671.     ListObjectInsert(NewPObj, i, NULL);
  672.     }
  673.  
  674.     return NewPObj;
  675. }
  676.  
  677. /*****************************************************************************
  678. * DESCRIPTION:                                                               M
  679. * Compute the zero points of a curve.                         M
  680. *                                                                            *
  681. * PARAMETERS:                                                                M
  682. *   PObj:      Curve to compute inflection points for.                       M
  683. *   Eps:       Accuracy of computation.                                      M
  684. *   Axis:      Of search for zeros.                         M
  685. *                                                                            *
  686. * RETURN VALUE:                                                              M
  687. *   IPObjectStruct *:  The zero set of curve PObj in axis Axis.             M
  688. *                                                                            *
  689. * KEYWORDS:                                                                  M
  690. *   CrvZeros                                                             M
  691. *****************************************************************************/
  692. IPObjectStruct *CrvZeros(IPObjectStruct *PObj, RealType *Eps, RealType *Axis)
  693. {
  694.     int i;
  695.     CagdPtStruct *ZPtsTmp,
  696.     *ZPts = SymbCrvZeroSet(PObj -> U.Crvs, (int) *Axis, *Eps);
  697.     IPObjectStruct
  698.     *PObjList = IPAllocObject("", IP_OBJ_LIST_OBJ, NULL);
  699.  
  700.     for (ZPtsTmp = ZPts, i = 0;
  701.      ZPtsTmp != NULL;
  702.      ZPtsTmp = ZPtsTmp -> Pnext, i++) {
  703.     ListObjectInsert(PObjList, i, GenNUMValObject(ZPtsTmp -> Pt[0]));
  704.     }
  705.  
  706.     CagdPtFreeList(ZPts);
  707.  
  708.     ListObjectInsert(PObjList, i, NULL);
  709.  
  710.     return PObjList;
  711. }
  712.  
  713. /*****************************************************************************
  714. * DESCRIPTION:                                                               M
  715. * Computes the extreme points of a curve.                     M
  716. *                                                                            *
  717. * PARAMETERS:                                                                M
  718. *   PObj:     Curve to compute extremum locations for.                       M
  719. *   Eps:      Accuracy control.                                              M
  720. *   Axis:     Of search for extremum points.                     M
  721. *                                                                            *
  722. * RETURN VALUE:                                                              M
  723. *   IPObjectStruct *:  The extremum set of curve PObj in axis Axis.         M
  724. *                                                                            *
  725. * KEYWORDS:                                                                  M
  726. *   CrvExtremes                                                              M
  727. *****************************************************************************/
  728. IPObjectStruct *CrvExtremes(IPObjectStruct *PObj,
  729.                 RealType *Eps,
  730.                 RealType *Axis)
  731. {
  732.     int i;
  733.     CagdPtStruct *ExPtsTmp,
  734.     *ExPts = SymbCrvExtremSet(PObj -> U.Crvs, (int) *Axis, *Eps);
  735.     IPObjectStruct
  736.     *PObjList = IPAllocObject("", IP_OBJ_LIST_OBJ, NULL);
  737.  
  738.     for (ExPtsTmp = ExPts, i = 0;
  739.      ExPtsTmp != NULL;
  740.      ExPtsTmp = ExPtsTmp -> Pnext, i++) {
  741.     ListObjectInsert(PObjList, i, GenNUMValObject(ExPtsTmp -> Pt[0]));
  742.     }
  743.  
  744.     CagdPtFreeList(ExPts);
  745.  
  746.     ListObjectInsert(PObjList, i, NULL);
  747.  
  748.     return PObjList;
  749. }
  750.  
  751. /*****************************************************************************
  752. * DESCRIPTION:                                                               M
  753. * Computes the intersection points of two curves.                 M
  754. *                                                                            *
  755. * PARAMETERS:                                                                M
  756. *   PObj1, PObj2:  Two curves to intersect.                                  M
  757. *   Eps:           Accuracy control.                                         M
  758. *   SelfInter:     Do we need to handle self intersection tests.             M
  759. *                                                                            *
  760. * RETURN VALUE:                                                              M
  761. *   IPObjectStruct *:   List of intersection locations. If SelfInter is TRUE M
  762. *                       assume PObj1 and PObj2 are the same and search for   M
  763. *            self intersections.                     M
  764. *                                                                            *
  765. * KEYWORDS:                                                                  M
  766. *   CrvCrvInter                                                              M
  767. *****************************************************************************/
  768. IPObjectStruct *CrvCrvInter(IPObjectStruct *PObj1,
  769.                 IPObjectStruct *PObj2,
  770.                 RealType *Eps,
  771.                 RealType *SelfInter)
  772. {
  773.     CagdSrfStruct
  774.     *DistSrf = SymbSrfDistCrvCrv(PObj1 -> U.Crvs, PObj2 -> U.Crvs);
  775.     IPObjectStruct *NewPObj;
  776.  
  777.     if (*Eps <= 0.0) {
  778.     CagdSrfStruct *DistSrf3D;
  779.     CagdRType UMin, UMax, VMin, VMax;
  780.  
  781.     CagdSrfDomain(DistSrf, &UMin, &UMax, &VMin, &VMax);
  782.     DistSrf3D = SymbPrmtSclrSrfTo3D(DistSrf, UMin, UMax, VMin, VMax);
  783.     CagdSrfFree(DistSrf);
  784.  
  785.     NewPObj = GenSRFObject(DistSrf3D);
  786.     }
  787.     else {
  788.     int i;
  789.     CagdPtStruct *IPtsTmp,
  790.         *IPts = SymbSrfDistFindPoints(DistSrf, *Eps,
  791.                       REAL_PTR_TO_INT(SelfInter));
  792.  
  793.     CagdSrfFree(DistSrf);
  794.  
  795.     NewPObj = IPAllocObject("", IP_OBJ_LIST_OBJ, NULL);
  796.  
  797.     for (IPtsTmp = IPts, i = 0;
  798.          IPtsTmp != NULL;
  799.          IPtsTmp = IPtsTmp -> Pnext, i++) {
  800.         ListObjectInsert(NewPObj, i, GenPTObject(&IPtsTmp -> Pt[0],
  801.                              &IPtsTmp -> Pt[1],
  802.                              &IPtsTmp -> Pt[2]));
  803.     }
  804.  
  805.     CagdPtFreeList(IPts);
  806.  
  807.     ListObjectInsert(NewPObj, i, NULL);
  808.     }
  809.  
  810.     return NewPObj;
  811. }
  812.  
  813. /*****************************************************************************
  814. * DESCRIPTION:                                                               M
  815. * Computes the closest/farest/distance square field from a curve to a given  M
  816. * point.                                     M
  817. *                                                                            *
  818. * PARAMETERS:                                                                M
  819. *   PCrv:     To consider its distace to Points.                             M
  820. *   Point:    To consider its distance to PCrv.                              M
  821. *   MinDist:  Do we need minimal distance (TRUE) or maximal distance (FALSE).M
  822. *   Eps:      If Eps > 0, computes the requested extremum location.          M
  823. *          Otherwise, computes the distance square scalar field.          M
  824. *                                                                            *
  825. * RETURN VALUE:                                                              M
  826. *   IPObjectStruct *:   Either extremum location or distance square field.   M
  827. *                                                                            *
  828. * KEYWORDS:                                                                  M
  829. *   CrvPointDist                                                             M
  830. *****************************************************************************/
  831. IPObjectStruct *CrvPointDist(IPObjectStruct *PCrv,
  832.                  PointType Point,
  833.                  RealType *MinDist,
  834.                  RealType *Eps)
  835. {
  836.     IPObjectStruct *NewPObj;
  837.  
  838.     if (*Eps > 0.0) {
  839.     NewPObj = GenNUMValObject(SymbDistCrvPoint(PCrv -> U.Crvs,
  840.                            Point,
  841.                            REAL_PTR_TO_INT(MinDist),
  842.                            *Eps));
  843.     }
  844.     else {
  845.     int i;
  846.     CagdPtStruct *IPtsTmp,
  847.         *IPts = SymbLclDistCrvPoint(PCrv -> U.Crvs, Point, -*Eps);
  848.  
  849.     NewPObj = IPAllocObject("", IP_OBJ_LIST_OBJ, NULL);
  850.  
  851.     for (IPtsTmp = IPts, i = 0;
  852.          IPtsTmp != NULL;
  853.          IPtsTmp = IPtsTmp -> Pnext, i++) {
  854.         ListObjectInsert(NewPObj, i, GenNUMValObject(IPtsTmp -> Pt[0]));
  855.     }
  856.  
  857.     CagdPtFreeList(IPts);
  858.  
  859.     ListObjectInsert(NewPObj, i, NULL);
  860.     }
  861.  
  862.     return NewPObj;
  863. }
  864.  
  865. /*****************************************************************************
  866. * DESCRIPTION:                                                               M
  867. * Computes the closest/farest/distance square field from a curve to a given  M
  868. * line.                                         M
  869. *                                                                            *
  870. * PARAMETERS:                                                                M
  871. *   PCrv:     To consider its distace to Line.                               M
  872. *   Point, Vec: Defining the line to consider its distance to PCrv.          M
  873. *   MinDist:  Do we need minimal distance (TRUE) or maximal distance (FALSE).M
  874. *   Eps:      If Eps > 0, computes the requested extremum location.          M
  875. *          Otherwise, computes the distance square scalar field.          M
  876. *                                                                            *
  877. * RETURN VALUE:                                                              M
  878. *   IPObjectStruct *:   Either extremum location or distance square field.   M
  879. *                                                                            *
  880. * KEYWORDS:                                                                  M
  881. *   CrvLineDist                                                              M
  882. *****************************************************************************/
  883. IPObjectStruct *CrvLineDist(IPObjectStruct *PCrv,
  884.                 PointType Point,
  885.                 VectorType Vec,
  886.                 RealType *MinDist,
  887.                 RealType *Eps)
  888. {
  889.     IPObjectStruct *NewPObj;
  890.     LineType Line;
  891.  
  892.     Line[0] = Vec[1];
  893.     Line[1] = -Vec[0];
  894.     Line[2] = -(Line[0] * Point[0] + Line[1] * Point[1]);
  895.  
  896.     if (*Eps > 0.0) {
  897.     NewPObj = GenNUMValObject(SymbDistCrvLine(PCrv -> U.Crvs,
  898.                           Line,
  899.                           REAL_PTR_TO_INT(MinDist),
  900.                           *Eps));
  901.     }
  902.     else {
  903.     int i;
  904.     CagdPtStruct *IPtsTmp,
  905.         *IPts = SymbLclDistCrvLine(PCrv -> U.Crvs, Line, -*Eps);
  906.  
  907.     NewPObj = IPAllocObject("", IP_OBJ_LIST_OBJ, NULL);
  908.  
  909.     for (IPtsTmp = IPts, i = 0;
  910.          IPtsTmp != NULL;
  911.          IPtsTmp = IPtsTmp -> Pnext, i++) {
  912.         ListObjectInsert(NewPObj, i, GenNUMValObject(IPtsTmp -> Pt[0]));
  913.     }
  914.  
  915.     CagdPtFreeList(IPts);
  916.  
  917.     ListObjectInsert(NewPObj, i, NULL);
  918.     }
  919.  
  920.     return NewPObj;
  921. }
  922.  
  923. /*****************************************************************************
  924. * DESCRIPTION:                                                               M
  925. * Composes a curve on a curve or a surface.                     M
  926. *                                                                            *
  927. * PARAMETERS:                                                                M
  928. *   PObj1:    A curve or a surface to compose.                               M
  929. *   PObj2:    A curve in the parametric space of PObj1.                      M
  930. *                                                                            *
  931. * RETURN VALUE:                                                              M
  932. *   IPObjectStruct *:   A composed curve of the form PObj1(Pobj2).           M
  933. *                                                                            *
  934. * KEYWORDS:                                                                  M
  935. *   CrvComposition                                                           M
  936. *****************************************************************************/
  937. IPObjectStruct *CrvComposition(IPObjectStruct *PObj1, IPObjectStruct *PObj2)
  938. {
  939.     IPObjectStruct
  940.     *Obj = NULL;
  941.  
  942.     if (IP_IS_CRV_OBJ(PObj1)) {
  943.     CagdCrvStruct
  944.         *Crv = SymbComposeCrvCrv(PObj1 -> U.Crvs, PObj2 -> U.Crvs);
  945.  
  946.     Obj = Crv ? GenCRVObject(Crv) : NULL;
  947.     }
  948.     else if (IP_IS_SRF_OBJ(PObj1)) {
  949.     CagdCrvStruct
  950.         *Crv = SymbComposeSrfCrv(PObj1 -> U.Srfs, PObj2 -> U.Crvs);
  951.  
  952.     Obj = Crv ? GenCRVObject(Crv) : NULL;
  953.     }
  954.     else {
  955.     IritFatalError("Curve or surface as first parameter only.");
  956.     }
  957.  
  958.     return Obj;
  959. }
  960.  
  961. /*****************************************************************************
  962. * DESCRIPTION:                                                               M
  963. * Computes a layout (prisa) of the given set of surfaces.             M
  964. *                                                                            *
  965. * PARAMETERS:                                                                M
  966. *   Srfs:             Surface to layout flat.                                M
  967. *   SamplesPerCurve:  Number of sample for piecewise linear curve         M
  968. *              approximation.                         M
  969. *   Epsilon:          Accuracy control.                                      M
  970. *   Dir:              Direction of subdivision. Either U or V.               M
  971. *   Space:            Spacing between the laid out pieces.                   M
  972. *                                                                            *
  973. * RETURN VALUE:                                                              M
  974. *   IPObjectStruct *:    A list of flat 2d surfaces approximating Srfs.      M
  975. *                                                                            *
  976. * KEYWORDS:                                                                  M
  977. *   SrfsPrisa                                                                M
  978. *****************************************************************************/
  979. IPObjectStruct *SrfsPrisa(IPObjectStruct *Srfs,
  980.               CagdRType *SamplesPerCurve,
  981.               CagdRType *Epsilon,
  982.               CagdRType *Dir,
  983.               CagdVType Space)
  984. {
  985.     int i;
  986.     IPObjectStruct *PObjList, *PObj;
  987.     CagdSrfStruct *Srf,
  988.     *PrisaSrfs = SymbAllPrisaSrfs(Srfs -> U.Srfs,
  989.                       REAL_PTR_TO_INT(SamplesPerCurve),
  990.                       *Epsilon,
  991.                       REAL_PTR_TO_INT(Dir),
  992.                       Space);
  993.  
  994.     /* Break the linear list into a list object. */
  995.     PObjList = IPAllocObject("", IP_OBJ_LIST_OBJ, NULL);
  996.     for (Srf = PrisaSrfs, i = 0; Srf != NULL; Srf = Srf -> Pnext, i++)
  997.     ListObjectInsert(PObjList, i, GenSRFObject(Srf));
  998.     ListObjectInsert(PObjList, i, NULL);
  999.     for (i = 0; (PObj = ListObjectGet(PObjList, i)) != NULL; i++)
  1000.     PObj -> U.Srfs -> Pnext = NULL;
  1001.  
  1002.     return PObjList;
  1003. }
  1004.  
  1005. /*****************************************************************************
  1006. * DESCRIPTION:                                                               M
  1007. * Computes an adaptive isocurve coverage to the given surface.             M
  1008. *                                                                            *
  1009. * PARAMETERS:                                                                M
  1010. *   Srf:         To compute adaptive isocurve coverage for.                  M
  1011. *   Dir:         Direction of adaptive isocurves. Either U or V.             M
  1012. *   Eps:         Coverage accuracy.                                          M
  1013. *   FullIso:     Do we want full isocurves or just trimmed ones.             M
  1014. *   SinglePath:  Do we want everying in one long curve?                      M
  1015. *                                                                            *
  1016. * RETURN VALUE:                                                              M
  1017. *   IPObjectStruct *:   An adaptive isocurve coverage for Srf.               M
  1018. *                                                                            *
  1019. * KEYWORDS:                                                                  M
  1020. *   SrfAdapIsoCurves                                                         M
  1021. *****************************************************************************/
  1022. IPObjectStruct *SrfAdapIsoCurves(IPObjectStruct *Srf,
  1023.                  CagdRType *Dir,
  1024.                  CagdRType *Eps,
  1025.                  CagdRType *FullIso,
  1026.                  CagdRType *SinglePath)
  1027. {
  1028.     IPObjectStruct *NewPObj;
  1029.     CagdCrvStruct
  1030.     *Crv = SymbAdapIsoExtract(Srf -> U.Srfs, NULL, NULL,
  1031.                   REAL_PTR_TO_INT(Dir),
  1032.                   *Eps, REAL_PTR_TO_INT(FullIso),
  1033.                   REAL_PTR_TO_INT(SinglePath));
  1034.  
  1035.     NewPObj = GenCRVObject(Crv);
  1036.  
  1037.     return NewPObj;
  1038. }
  1039. /*****************************************************************************
  1040. * DESCRIPTION:                                                               M
  1041. * Returns the parametric domain of the given curve or surface, trimmed       M
  1042. * surface or a trivariate.                                 M
  1043. *                                                                            *
  1044. * PARAMETERS:                                                                M
  1045. *   FreeformObj:  To return its parametric domain.                           M
  1046. *                                                                            *
  1047. * RETURN VALUE:                                                              M
  1048. *   IPObjectStruct *:  A list of two (curve) or four (surface, trimmed       M
  1049. *                      surface) or six (trivariate) numbers representing     M
  1050. *               the parametric domain of FreeformObj.             M
  1051. *                                                                            *
  1052. * KEYWORDS:                                                                  M
  1053. *   GetFreefromParamDomain                                                   M
  1054. *****************************************************************************/
  1055. IPObjectStruct *GetFreefromParamDomain(IPObjectStruct *FreeformObj)
  1056. {
  1057.     int i, n;
  1058.     IPObjectStruct *NewPObj;
  1059.     CagdRType Domain[6];
  1060.  
  1061.     if (IP_IS_CRV_OBJ(FreeformObj)) {
  1062.     CagdCrvDomain(FreeformObj -> U.Crvs, &Domain[0], &Domain[1]);
  1063.     n = 2;
  1064.     }
  1065.     else if (IP_IS_SRF_OBJ(FreeformObj)) {
  1066.     CagdSrfDomain(FreeformObj -> U.Srfs,
  1067.               &Domain[0], &Domain[1], &Domain[2], &Domain[3]);
  1068.     n = 4;
  1069.     }
  1070.     else if (IP_IS_TRIMSRF_OBJ(FreeformObj)) {
  1071.     CagdSrfDomain(FreeformObj -> U.TrimSrfs -> Srf,
  1072.               &Domain[0], &Domain[1], &Domain[2], &Domain[3]);
  1073.     n = 4;
  1074.     }
  1075.     else if (IP_IS_TRIVAR_OBJ(FreeformObj)) {
  1076.     TrivTVDomain(FreeformObj -> U.Trivars,
  1077.              &Domain[0], &Domain[1],
  1078.              &Domain[2], &Domain[3],
  1079.              &Domain[4], &Domain[5]);
  1080.     n = 6;
  1081.     }
  1082.     else {
  1083.     IritFatalError("Curve or (trimmed) surface or trivariate as first parameter only.");
  1084.     return NULL;
  1085.     }
  1086.  
  1087.     NewPObj = IPAllocObject("", IP_OBJ_LIST_OBJ, NULL);
  1088.     for (i = 0; i < n ; i++)
  1089.     ListObjectInsert(NewPObj, i, GenNUMValObject(Domain[i]));
  1090.     ListObjectInsert(NewPObj, i, NULL);
  1091.  
  1092.     return NewPObj;
  1093. }
  1094.  
  1095. /*****************************************************************************
  1096. * DESCRIPTION:                                                               M
  1097. * Computes a least square approximation/Interpolation of 1d pt data set.     M
  1098. *                                                                            *
  1099. * PARAMETERS:                                                                M
  1100. *   PtObjList:   Points to least squares fit.                                M
  1101. *   ROrder:      Order of fitting curve.                                     M
  1102. *   RCrvSize:    Size of fitting curve.                                      M
  1103. *   RParamType:  Point type.                                                 M
  1104. *                                                                            *
  1105. * RETURN VALUE:                                                              M
  1106. *   IPObjectStruct *:  A Bspline curve that least squares fits PtObjList.    M
  1107. *                                                                            *
  1108. * KEYWORDS:                                                                  M
  1109. *   CrvLeastSquarePtData                                                     M
  1110. *****************************************************************************/
  1111. IPObjectStruct *CrvLeastSquarePtData(IPObjectStruct *PtObjList,
  1112.                      CagdRType *ROrder,
  1113.                      CagdRType *RCrvSize,
  1114.                      CagdRType *RParamType)
  1115. {
  1116.     int i,
  1117.     Order = REAL_PTR_TO_INT(ROrder),
  1118.     CrvSize = REAL_PTR_TO_INT(RCrvSize);
  1119.     CagdParametrizationType
  1120.     ParamType = REAL_PTR_TO_INT(RParamType);
  1121.     CagdPtStruct
  1122.     *Pt = NULL,
  1123.     *PtList = NULL;
  1124.     CagdCrvStruct
  1125.     *Crv = NULL;
  1126.     IPObjectStruct *PtObj;
  1127.  
  1128.     if (!IP_IS_OLST_OBJ(PtObjList))
  1129.     IritFatalError("CINTERP: Not object list object!");
  1130.  
  1131.     for (i = 0; (PtObj = ListObjectGet(PtObjList, i)) != NULL; i++) {
  1132.     IPObjectStruct *PointObj;
  1133.  
  1134.     if (!IP_IS_CTLPT_OBJ(PtObj) &&
  1135.         !IP_IS_POINT_OBJ(PtObj) &&
  1136.         !IP_IS_VEC_OBJ(PtObj)) {
  1137.         CagdPtFreeList(PtList);
  1138.         IritPrsrFatalError("Non point object found in list");
  1139.         return NULL;
  1140.     }
  1141.  
  1142.     PointObj = IritPrsrCoerceObjectTo(PtObj, IP_OBJ_POINT);
  1143.     if (PtList == NULL)
  1144.         PtList = Pt = CagdPtNew();
  1145.     else {
  1146.         Pt -> Pnext = CagdPtNew();
  1147.         Pt = Pt -> Pnext;
  1148.     }
  1149.     PT_COPY(Pt -> Pt, PointObj -> U.Pt);
  1150.     IPFreeObject(PointObj);
  1151.     }
  1152.     
  1153.     if (i < 3 || i < Order ||
  1154.     (CrvSize != 0 && (i < CrvSize || CrvSize < Order))) {
  1155.     IritPrsrFatalError("Number of points to interpolate does not match order/length of curve.");
  1156.     }
  1157.     else {
  1158.     Crv = BspCrvInterpPts(PtList, Order, CrvSize, ParamType);
  1159.     }
  1160.  
  1161.     CagdPtFreeList(PtList);
  1162.  
  1163.     return Crv ? GenCRVObject(Crv) : NULL;
  1164. }
  1165.  
  1166. /*****************************************************************************
  1167. * DESCRIPTION:                                                               M
  1168. * Computes a least square approximation/Interpolation of 2d pt data set.     M
  1169. *                                                                            *
  1170. * PARAMETERS:                                                                M
  1171. *   LstObjList:   List of point lists.                                       M
  1172. *   RUOrder:      Uorder of fitting surface.                                 M
  1173. *   RVOrder:      Vorder of fitting surface.                                 M
  1174. *   RUSize:       USize of fitting curve.                                    M
  1175. *   RVSize:       VSize of fitting curve.                                    M
  1176. *   RParamType:   Point type.                                                M
  1177. *                                                                            *
  1178. * RETURN VALUE:                                                              M
  1179. *   IPObjectStruct *:   A Bspline surface that least square fits LstObjList. M
  1180. *                                                                            *
  1181. * KEYWORDS:                                                                  M
  1182. *   SrfLeastSquarePtData                                                     M
  1183. *****************************************************************************/
  1184. IPObjectStruct *SrfLeastSquarePtData(IPObjectStruct *LstObjList,
  1185.                      CagdRType *RUOrder,
  1186.                      CagdRType *RVOrder,
  1187.                      CagdRType *RUSize,
  1188.                      CagdRType *RVSize,
  1189.                      CagdRType *RParamType)
  1190. {
  1191.     int i, j, k,
  1192.     NumVertices = 0,
  1193.     NumLists = 0,
  1194.     NumVerticesFirst = 0,
  1195.     UOrder = REAL_PTR_TO_INT(RUOrder),
  1196.     VOrder = REAL_PTR_TO_INT(RVOrder),
  1197.     USize = REAL_PTR_TO_INT(RUSize),
  1198.     VSize = REAL_PTR_TO_INT(RVSize);
  1199.     CagdParametrizationType
  1200.     ParamType = REAL_PTR_TO_INT(RParamType);
  1201.     CagdPtStruct **PtListArray, *Pt;
  1202.     CagdSrfStruct
  1203.     *Srf = NULL;
  1204.     IPObjectStruct *LstObj, *PtObj;
  1205.  
  1206.     if (!IP_IS_OLST_OBJ(LstObjList))
  1207.     IritFatalError("SINTERP: Not object list object!");
  1208.  
  1209.     while ((LstObj = ListObjectGet(LstObjList, NumLists)) != NULL) {
  1210.     if (!IP_IS_OLST_OBJ(LstObj))
  1211.         return NULL;
  1212.  
  1213.         NumVertices = -1;
  1214.         while ((PtObj = ListObjectGet(LstObj, ++NumVertices)) != NULL) {
  1215.         if (!IP_IS_CTLPT_OBJ(PtObj) &&
  1216.         !IP_IS_POINT_OBJ(PtObj) &&
  1217.         !IP_IS_VEC_OBJ(PtObj)) {
  1218.         return NULL;
  1219.         }
  1220.     }
  1221.  
  1222.     if (NumLists++ == 0)
  1223.         NumVerticesFirst = NumVertices;
  1224.         else
  1225.         if (NumVerticesFirst != NumVertices)
  1226.             return NULL;
  1227.     }
  1228.  
  1229.     /* Coerce all points to a point type, in place. */
  1230.     while ((LstObj = ListObjectGet(LstObjList, NumLists)) != NULL)
  1231.     IritPrsrCoercePtsListTo(LstObj, IP_OBJ_POINT);
  1232.  
  1233.     PtListArray = (CagdPtStruct **)
  1234.     IritMalloc(sizeof(CagdPtStruct *) * (NumLists + 1));
  1235.     PtListArray[NumLists] = NULL;
  1236.  
  1237.     for (i = 0; (LstObj = ListObjectGet(LstObjList, i)) != NULL; i++) {
  1238.     Pt = PtListArray[i] = CagdPtNew();
  1239.     for (j = 0; (PtObj = ListObjectGet(LstObj, j)) != NULL; j++) {
  1240.         for (k = 0; k < 3; k++)
  1241.         Pt -> Pt[k] = PtObj -> U.Pt[k];
  1242.  
  1243.         if (j < NumVertices - 1) {
  1244.         Pt -> Pnext = CagdPtNew();
  1245.         Pt = Pt -> Pnext;
  1246.         }
  1247.     }
  1248.     }
  1249.     
  1250.     if (NumLists < 3 ||    NumVertices < 3 ||
  1251.     NumLists < UOrder || NumVertices < VOrder ||
  1252.     (USize != 0 && (NumLists < USize || USize < UOrder)) ||
  1253.     (VSize != 0 && (NumVertices < VSize || VSize < VOrder))) {
  1254.     IritPrsrFatalError("Number of points to interpolate does not match order/length of curve.");
  1255.     }
  1256.     else {
  1257.     Srf = BspSrfInterpPts(PtListArray, UOrder, VOrder,
  1258.                   USize, VSize, ParamType);
  1259.     }
  1260.  
  1261.     for (i = 0; i < NumLists; i++)
  1262.     CagdPtFreeList(PtListArray[i]);
  1263.     IritFree((VoidPtr) PtListArray);
  1264.  
  1265.     return Srf ? GenSRFObject(Srf) : NULL;
  1266. }
  1267.  
  1268. /*****************************************************************************
  1269. * DESCRIPTION:                                                               M
  1270. *  Routine to fetch the resolution parameter from the RESOLUTION object.     M
  1271. *  If ClipToMin TRUE, the Resolution is clipped to not be below MIN_RES.     M
  1272. *                                                                            *
  1273. * PARAMETERS:                                                                M
  1274. *   ClipToMin:    Do we want a lower bound?                                  M
  1275. *                                                                            *
  1276. * RETURN VALUE:                                                              M
  1277. *   int:          Current resolution level.                                  M
  1278. *                                                                            *
  1279. * KEYWORDS:                                                                  M
  1280. *   GetResolution                                                            M
  1281. *****************************************************************************/
  1282. int GetResolution(int ClipToMin)
  1283. {
  1284.     int Resolution;
  1285.     IPObjectStruct *PObj = GetObject("RESOLUTION");
  1286.  
  1287.     if (PObj == NULL || !IP_IS_NUM_OBJ(PObj)) {
  1288.     IritPrsrFatalError("No numeric object name RESOLUTION is defined");
  1289.     Resolution = DEFAULT_RESOLUTION;
  1290.     }
  1291.     else {
  1292.     if (ClipToMin) {
  1293.         Resolution = MAX(((int) (PObj -> U.R)), MIN_RESOLUTION);
  1294.  
  1295.         Resolution = (Resolution / 2) * 2;        /* Make sure its even. */
  1296.     }
  1297.     else {
  1298.         Resolution = (int) (PObj -> U.R);
  1299.     }
  1300.     }
  1301.  
  1302.     return Resolution;
  1303. }
  1304.  
  1305. /*****************************************************************************
  1306. * DESCRIPTION:                                                               M
  1307. * Computes a multi-resolution decomposition for a given curve using least    M
  1308. * squares. Returned is a list of curves of the decomposition.                M
  1309. *                                                                            *
  1310. * PARAMETERS:                                                                M
  1311. *   CrvObj:     Curve to multi-resolution decompose.                         M
  1312. *   Discont:    Do we want to preserve discontinuities?                      M
  1313. *                                                                            *
  1314. * RETURN VALUE:                                                              M
  1315. *   IPObjectStruct *:  A list object of all the curves of the decomposition. M
  1316. *                                                                            *
  1317. * KEYWORDS:                                                                  M
  1318. *   CurveMultiResDecomp                                                      M
  1319. *****************************************************************************/
  1320. IPObjectStruct *CurveMultiResDecomp(IPObjectStruct *CrvObj, RealType *Discont)
  1321. {
  1322.     int i;
  1323.     IPObjectStruct *CrvObjList;
  1324.     SymbMultiResCrvStruct
  1325.     *MResCrv = SymbCrvMultiResDecomp(CrvObj -> U.Crvs,
  1326.                      REAL_PTR_TO_INT(Discont));
  1327.  
  1328.     if (MResCrv == NULL) {
  1329.         IritPrsrFatalError("Multi resolution decomposition failed.");
  1330.         return NULL;
  1331.     }
  1332.  
  1333.     CrvObjList = IPAllocObject("", IP_OBJ_LIST_OBJ, NULL);
  1334.  
  1335.     for (i = 0; i < MResCrv -> Levels; i++)
  1336.     ListObjectInsert(CrvObjList, i,
  1337.              GenCRVObject(CagdCrvCopy(MResCrv -> HieCrv[i])));
  1338.  
  1339.     ListObjectInsert(CrvObjList, i, NULL);
  1340.  
  1341.     SymbCrvMultiResFree(MResCrv);
  1342.  
  1343.     return CrvObjList;
  1344. }
  1345.